package com.acce.core.filter;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.acce.core.config.ReturnCodes;
import com.acce.core.pojo.UserList;
import com.acce.core.utils.Constants;
import com.acce.core.utils.PropertiesUtil;
import com.acce.core.utils.TokenUtils;
import com.acce.core.utils.Utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

/**
 * Servlet Filter implementation class AccessFilter
 */
@WebFilter("/AccessFilter")
public class AccessFilter implements Filter {
	
	Logger logger = Logger.getLogger(AccessFilter.class);
	String authPath = PropertiesUtil.getInstance().getProperties("/system.properties").getProperty("authPath");
	String wapeWechatAppID = PropertiesUtil.getInstance().getProperties("/system.properties").getProperty("wapeWechatAppID");
	
	private List<String> special;

    /**
     * Default constructor. 
     */
    public AccessFilter() {
        // TODO Auto-generated constructor stub
    }

	/**
	 * @see Filter#destroy()
	 */
	public void destroy() {
		// TODO Auto-generated method stub
	}

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest res = (HttpServletRequest) request;
		HttpServletResponse rep = (HttpServletResponse) response;
		//过滤器作用，过滤所有请求，如果是微信的请求(openId,isWX)，自动登录，拉取用户信息，对请求放行
		//如果不是微信请求，判断session过期，过期跳转到登录页面，没过期请求放行。
		String openId = res.getParameter("openId");
		String isWX = res.getParameter("isWX");
		String atUserId = (String) res.getSession().getAttribute("atUserId");
		String serviceCode = res.getParameter("serviceCode");
		logger.info("wape-web::doFilter::filter serviceCode::" + serviceCode);
		logger.info("wape-web::doFilter::filter atUserId::" + atUserId);
		logger.info("wape-web::doFilter::filter openId::" + openId);
		String ipaddr = "";
		try {
			ipaddr = Utils.getIpAddress(res);
		} catch (IOException e2) {
			logger.error("wape-web::doFilter::ip not get::" + e2.getMessage());
		}
		String device;
		if(!StringUtils.isEmpty(openId) && "yes".equals(isWX)){
	    	device = "wx";
		}else{
			device = "pc";
		}
	    String mac = "00-00-00-00-000";
		boolean isSpecial = false;
		String code = "";
		//判断是否是例外请求
		logger.info("wape-web::doFilter::special size::" + special.size());
		for(int i = 0, size = special.size(); i < size; i++){
			code = special.get(i);
			logger.info("wape-web::doFilter::special::" + serviceCode + "eq" + code);
			if(serviceCode.equals(code)){
				isSpecial = true;
				break;
			}
		}
		logger.info("wape-web::doFilter::isSpecial :" + isSpecial);
		if(isSpecial){ //是例外直接放行
			//预留
			logger.info("wape-web::doFilter::filter OK");
		}else{ //不是例外
			//对跳转请求进行特殊处理
			if("WJ9999".equals(serviceCode)){
				//拦截微信的登录绑定请求
				String targetURL = res.getParameter("targetURL");
				logger.info("wape-web::doFilter::targetURL :" + targetURL);
				if("w-login".equals(targetURL)){
					String token4 = "411e7bc272a421b44802a9f608a740e5ca74872a";
					String timestamp4 = Utils.getCurrTimeMillions();
				    String nonce4 = Utils.getNonce();
				    String sign4 = "";
					try {
						sign4 = TokenUtils.getSign(token4, timestamp4, nonce4);
					} catch (NoSuchAlgorithmException e3) {
						logger.error("sign4 make error::" + e3.getMessage());
					}
				    String editUserId4 = openId;
				    String editTime4 = timestamp4;
				    JSONObject businessJson4 = new JSONObject();
				    businessJson4.put("openId", openId);
				    businessJson4.put("registerNum", "99999999999"); //系统号码，这里为了判断openId是否已绑定
				    String business4 = businessJson4.toString();
					Map<String, String> params4 = new HashMap<String, String>();
					params4.put("serviceCode", "1001W03");
					params4.put("sign", sign4);
					params4.put("timestamp", timestamp4);
					params4.put("nonce", nonce4);
					params4.put("editUserId", editUserId4);
					params4.put("editTime", editTime4);
					params4.put("ipaddr", ipaddr);
					params4.put("device", device);
					params4.put("mac", mac);
					params4.put("business", business4);
					logger.info("wape-web::doFilter::business4 :" + business4);
					String resultString4 = Utils.sendhttp(authPath, params4);
					logger.info("wape-web::doFilter::business4 :" + resultString4);
					JSONObject resultJson=JSON.parseObject(resultString4);
					String returnCode4 = resultJson.getString("returnCode");
					String returnMsg4 = resultJson.getString("returnMsg");
					logger.info("wape-web::doFilter::returnCode4 :" + returnCode4);
					logger.info("wape-web::doFilter::returnMsg4 :" + returnMsg4);
					if(ReturnCodes.OPENID_HAVE_BINDING.equals(returnCode4)){ //openId已绑定则不允许通过
						String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + wapeWechatAppID +"&redirect_uri="
								+ Constants.WEB_SERVICE_ADDR + "/3g/mine/mine.jsp?openId=" + openId + "&isWX=yes"
								+ "&returnCode=" + returnCode4 + "&returnMsg=" + returnMsg4
								+ "&response_type=code&scope=snsapi_userinfo&state=STATE&connect_redirect=1#wechat_redirect";
						logger.info("wape-web::doFilter::openId have binding send::" + url);
						rep.sendRedirect(url);
						return;
					}
				}
			}else{
				if(!StringUtils.isEmpty(openId) && "yes".equals(isWX)){ //是微信
					boolean autoFlag = false; //是否可自动登录
					if(null == atUserId){ //过期，自动登录
						logger.info("wape-web::doFilter::session is null,expire::");
						autoFlag = true;
					}else{ //没过期,判断是否被挤掉
						logger.info("wape-web::doFilter::session is exists,not expire::");
						//判断账号是否被挤掉
						String token1 = (String) res.getSession().getAttribute("token");
						String timestamp1 = Utils.getCurrTimeMillions();
					    String nonce1 = Utils.getNonce();
					    String sign1 = "";
						try {
							sign1 = TokenUtils.getSign(token1, timestamp1, nonce1);
						} catch (NoSuchAlgorithmException e3) {
							logger.error("wape-web::doFilter::sign1 make error::" + e3.getMessage());
						}
					    String editUserId1 = atUserId;
					    String editTime1 = timestamp1;
					    JSONObject businessJson1 = new JSONObject();
					    businessJson1.put("atUserId", atUserId);
					    String business1 = businessJson1.toString();
						Map<String, String> params1 = new HashMap<String, String>();
						params1.put("serviceCode", "1001W04");
						params1.put("sign", sign1);
						params1.put("timestamp", timestamp1);
						params1.put("nonce", nonce1);
						params1.put("editUserId", editUserId1);
						params1.put("editTime", editTime1);
						params1.put("ipaddr", ipaddr);
						params1.put("device", device);
						params1.put("mac", mac);
						params1.put("business", business1);
						logger.info("wape-web::doFilter::business1::" + business1);
						String resultString1 = Utils.sendhttp(authPath, params1);
						logger.info("wape-web::doFilter::resultString1::" + resultString1);
						JSONObject resultJson1=JSON.parseObject(resultString1);
						if(!"200".equals(resultJson1.getString("returnCode"))){ //非200说明签名不一致，被挤掉了
							logger.info("wape-web::doFilter::other login::" + resultString1);
							autoFlag = true;
						}
						if(autoFlag){
							//自动登录
							String token2 = "411e7bc272a421b44802a9f608a740e5ca74872a";
							String timestamp2 = Utils.getCurrTimeMillions();
						    String nonce2 = Utils.getNonce();
						    String sign2 = "";
							try {
								sign2 = TokenUtils.getSign(token2, timestamp2, nonce2);
							} catch (NoSuchAlgorithmException e3) {
								logger.error("wape-web::doFilter::sign2 make error::" + e3.getMessage());
							}
						    String editUserId2 = openId;
						    String editTime2 = timestamp2;
						    JSONObject businessJson2 = new JSONObject();
						    businessJson2.put("openId", openId);
						    String business2 = businessJson2.toString();
							Map<String, String> params2 = new HashMap<String, String>();
							params2.put("serviceCode", "1001W02");
							params2.put("sign", sign2);
							params2.put("timestamp", timestamp2);
							params2.put("nonce", nonce2);
							params2.put("editUserId", editUserId2);
							params2.put("editTime", editTime2);
							params2.put("ipaddr", ipaddr);
							params2.put("device", device);
							params2.put("mac", mac);
							params2.put("business", business2);
							logger.info("wape-web::doFilter::business2 is :" + business2);
							String resultString2 = Utils.sendhttp(authPath, params2);
							logger.info("wape-web::doFilter::resultString2::" + resultString2);
							JSONObject resultJson2=JSON.parseObject(resultString2);
							String returnCode2 = resultJson2.getString("returnCode");
							String returnMsg2 = resultJson2.getString("returnMsg");
							logger.info("wape-web::doFilter::return returnCode2::" + returnCode2);
							logger.info("wape-web::doFilter::return returnMsg2::" + returnMsg2);
							if("200".equals(returnCode2)){
								logger.info("wape-web::doFilter::login in::");
					        	JSONObject result2 = JSON.parseObject(resultJson2.getString("result"));
					        	atUserId = result2.getString("atUserId");
					        	String token3 = result2.getString("token");
					        	//保存用户验证信息
					        	res.getSession().setAttribute("atUserId", atUserId);
					        	res.getSession().setAttribute("openId", openId);
					        	res.getSession().setAttribute("token", token3);
					        	//拉取用户信息
					        	String timestamp3 = Utils.getCurrTimeMillions();
							    String nonce3 = Utils.getNonce();
							    String editTime3 = timestamp3;
					        	String sign3 = "";
								try {
									sign3 = TokenUtils.getSign(token3, timestamp3, nonce3);
								} catch (NoSuchAlgorithmException e3) {
									logger.error("wape-web::doFilter::sign3 make error::" + e3.getMessage());
								}
				        		JSONObject businessJson3 = new JSONObject();
				        		businessJson3.put("atUserId", atUserId);
				        		businessJson3.put("token", token3);
				        	    String business3 = businessJson3.toJSONString();
				        	    Map<String, String> params3 = new HashMap<String, String>();
				        	    params3.put("serviceCode", "5003U01");
				        	    params3.put("sign", sign3);
				        	    params3.put("timestamp", timestamp3);
				        	    params3.put("nonce", nonce3);
				        	    params3.put("editUserId", atUserId);
				        	    params3.put("editTime", editTime3);
				        	    params3.put("ipaddr", ipaddr);
				        	    params3.put("device", device);
				        	    params3.put("mac", mac);
				        	    params3.put("business", business3);
				        	    logger.info("wape-web::doFilter::business3::" + business3);
				                String resultString3 = Utils.sendhttp(authPath, params3);
				                logger.info("wape-web::doFilter::resultString3::" + resultString3);
				                JSONObject resultJson3=JSON.parseObject(resultString3);
				                String returnCode3 = resultJson3.getString("returnCode");
				    			String returnMsg3 = resultJson3.getString("returnMsg");
				    			logger.info("wape-web::doFilter::returnCode3::" + returnCode3);
				    			logger.info("wape-web::doFilter::returnMsg3::" + returnMsg3);
				                if("200".equals(returnCode3)){
				                	logger.info("wape-web::doFilter::query user info suceess");
				                	JSON son = JSON.parseObject(resultJson3.getString("result"));
				                    UserList user = JSONObject.toJavaObject(son, UserList.class);
				                    res.getSession().setAttribute("user", user);
				                }else{ //拉取用户信息异常
				                	String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + wapeWechatAppID +"&redirect_uri="
											+ Constants.WEB_SERVICE_ADDR + "/3g/404.jsp?openId=" + openId + "&returnCode=" + returnCode3
											+ "&returnMsg=" + returnMsg3
											+ "&isWX=yes&response_type=code&scope=snsapi_userinfo&state=STATE&connect_redirect=1#wechat_redirect";
				                	logger.info("wape-web::doFilter::query user info error send::" + url);
									rep.sendRedirect(url);
									return;
				                }
							}else{ //自动登录不成功
								String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + wapeWechatAppID +"&redirect_uri="
										+ Constants.WEB_SERVICE_ADDR + "/3g/404.jsp?openId=" + openId + "&returnCode=" + returnCode2
										+ "&returnMsg=" + returnMsg2
										+ "&isWX=yes&response_type=code&scope=snsapi_userinfo&state=STATE&connect_redirect=1#wechat_redirect";
								logger.info("wape-web::doFilter::auto login error send::" + url);
								rep.sendRedirect(url);
								return;
							}
						}
					}
				}else{ //不是微信
					logger.info("wape-web::doFilter::not WeChat");
					if(null == atUserId){
						logger.info("wape-web::doFilter::session is null send login.jsp");
						String path = request.getServletContext().getContextPath();
						rep.sendRedirect(path + "/3g/login.jsp");
						return;
					}
				}
			}
		}
		
		//1.判断当前请求如果是微信autoLogin自动登录的请求时, 需要将openId设置到session的同时在cookie中也设置一份
		//session 里 取openId, 如果有的话, 设置cookie中openId
		Cookie cookie = new Cookie("cookiename","111111111");
		cookie.setPath("/");
		cookie.setMaxAge(3600);
		rep.addCookie(cookie);
		chain.doFilter(res, rep);
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		logger.info("wape-web::init::");
		special = new ArrayList<String>();
		special.add("5001U01");
		special.add("5001U02");
		special.add("5002U01");
		special.add("5004U02");
		special.add("1001W01");
		special.add("1001W02");
		special.add("1001W05");
	}
	
}
